﻿using HMS.TenantServer.Authentication.Abstractions;
using HMS.TenantServer.Authentication.Jwt;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using System.Net;

namespace Microsoft.Extensions.DependencyInjection;

public static class ServiceConllectionExtensions
{
    public static IServiceCollection AddJwt(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddHttpContextAccessor();

        services.AddHttpClient("oauth").ConfigurePrimaryHttpMessageHandler(provider =>
        {
            return new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = delegate { return true; },
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };
        });

        services.AddScoped<UserPoolBase, JwtUserPool>();
        services.AddSingleton<JwtTokenHandler>();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, opts =>
            {
                opts.BackchannelHttpHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                };

                var issuer = configuration["Jwt:Issuer"];
                var audience = configuration["Jwt:Audience"];
                var securityKey = configuration["Jwt:SecurityKey"];

                var symmetricKey = new SymmetricSecurityKey(Convert.FromBase64String(securityKey!));

                opts.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer = issuer,
                    ValidAudience = audience,
                    IssuerSigningKey = symmetricKey,

                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateIssuerSigningKey = true,

                    ValidateLifetime = true,
                    RequireExpirationTime = true,
                    ClockSkew = TimeSpan.FromMinutes(30)
                };

                opts.SaveToken = true;
                opts.IncludeErrorDetails = true;

                IdentityModelEventSource.ShowPII = true;
            });

        services.AddTransient<IStartupFilter, JwtAuthenticationMiddleware>();

        return services;
    }
}